/**
 *
 * Author: huangxinhao.cn@gmail.com
 * Time: 2010-7-17
 * 
 */

function isInArray( arr, v ){
    var i = 0;
    for( i = 0; i < arr.length; i++ ){
        if( arr[i] == v ){
            return true;
        }
    }
    return false;
}
function arrayRemoveValue( arr, value ){
    var arr2 = [];
    var i = 0;
    for( i = 0; i < arr.length; i++ ){
        if( arr[i] != value ){
            arr2.push( arr[i] );
        }
    }
    return arr2;
}



_LocalDB = function(){};
_LocalDB.prototype.store = null;
_LocalDB.prototype.onReady = [];
_LocalDB.prototype.ready = function( callback ){
    if( typeof(callback) == "function" ){
        if( this.store.store ){
            callback();
        }else{
            this.onReady.push( callback );
        }
    }
};
_LocalDB.prototype.init = function( name, cfg ){
    var obj = this;
    this.store = this._searchStore( name );
    if( this.store ){
        this.store.init( "xinstore", cfg, function(){
            while( obj.onReady.length > 0 ){
                var fn = obj.onReady.pop();
                fn();
            }
        });
    }
};
_LocalDB.prototype._searchStore = function( name ){
    var i;
    for( i = 0; i < this.dbs.length; i++ ){
        var s = this.dbs[i];
        if( name ){
            if( s.type == name ){
                return s;
            }
        }else{
            if( s.test() ){
                return s;
            }
        }
    }
    return null;
};
_LocalDB.prototype.key_dbs = function(){
    return "dbs";  
};
_LocalDB.prototype.resetDatabaseNames = function( dbs ){
    var key = this.key_dbs();
    if( dbs.length < 1 ){
        this.store.remove( key );
    }else{
        var value = JSON.stringify( dbs );
        this.store.set( key, value );
    }
    return true;
};
_LocalDB.prototype.createDatabase = function( dbname ){
    var dbs = this.databases();
    if( !isInArray( dbs, dbname ) ){
        dbs.push( dbname );
        this.resetDatabaseNames( dbs );
    }
    
    var db = new LocalDB_DB();
    db.name = dbname;
    db.store = this.store;
    return db;
};
_LocalDB.prototype.dropDatabase = function( dbname ){
    var dbs = this.databases();
    if( !isInArray( dbs, dbname ) ){
        return true;
    }
    var db = this.createDatabase( dbname );
    var tbs = db.tables();
    var i;
    for( i = 0; i < tbs.length; i++ ){
        var tbname = tbs[i];
        db.dropTable( tbname );
    }
    dbs = arrayRemoveValue( dbs, dbname );
    this.resetDatabaseNames( dbs );
    return true;
};
_LocalDB.prototype.databases = function(){
    var key = this.key_dbs();
    var value = this.store.get( key );
    if( !value ){
        return [];
    }
    var dbs = JSON.parse( value );
    if( dbs ){
        return dbs;
    }
    return [];
};

LocalDB_DB = function(){};
LocalDB_DB.prototype.store = null;
LocalDB_DB.prototype.name = "";
LocalDB_DB.prototype.key_tbs = function(){
    return this.name + ".tbs";
};
LocalDB_DB.prototype.resetTableNames = function( tbs ){
    var key = this.key_tbs();
    if( tbs.length < 1 ){
        this.store.remove( key );
    }else{
        var value = JSON.stringify( tbs );
        this.store.set( key, value );
    }
    return true;
};
LocalDB_DB.prototype.createTable = function( tbname ){
    var tbs = this.tables();
    if( !isInArray( tbs, tbname ) ){
        tbs.push( tbname );
        this.resetTableNames( tbs );
    };
    
    var tb = new LocalDB_TB();
    tb.name = tbname;
    tb.db = this;
    return tb;
};
LocalDB_DB.prototype.dropTable = function( tbname ){
    var tbs = this.tables();
    if( !isInArray( tbs, tbname ) ){
        return true;
    }

    var tb = this.createTable( tbname );
    tb.clear();

    tbs = arrayRemoveValue( tbs, tbname );
    this.resetTableNames( tbs );
    
    return true;
};
LocalDB_DB.prototype.tables = function(){
    var key = this.key_tbs();
    var value = this.store.get( key );
    if( !value ){
        return [];
    }
    var tbs = JSON.parse( value );
    if( tbs ){
        return tbs;
    }
    return [];
};


LocalDB_TB = function(){};
LocalDB_TB.prototype.name = "";
LocalDB_TB.prototype.db = null;
LocalDB_TB.prototype.key_rs = function(){
    return this.db.name + "." + this.name + ".rs";
};
LocalDB_TB.prototype.key_r = function( id ){
    return this.db.name + "." + this.name + "." + id;
};
LocalDB_TB.prototype.recordIDs = function(){
    var key = this.key_rs();
    var value = this.db.store.get( key );
    if( !value ){
        return [];
    }
    var ids = JSON.parse( value );
    if( ids ){
        return ids;
    }
    return [];
};
LocalDB_TB.prototype.setRecordIDs = function( ids ){
    var key = this.key_rs();
    if( ids.length < 1 ){
        this.db.store.remove( key );
    }else{
        var value = JSON.stringify( ids );
        this.db.store.set( key, value );
    }
};
LocalDB_TB.prototype.newID = function( ids ){
    var max = -99;
    var i = 0;
    for( i = 0; i < ids.length; i++ ){
        if( max < ids[i] ){
            max = ids[i];
        }
    }
    if( max < 0 ){
        return 1;
    }
    return max + 1;
};
LocalDB_TB.prototype.insert = function( rec ){
    var rsids = this.recordIDs();
    var id = this.newID( rsids );
    var key = this.key_r( id );
    var value = JSON.stringify( rec );
    this.db.store.set( key, value );
    
    rsids.push( id );
    this.setRecordIDs( rsids );
    return id;
};
LocalDB_TB.prototype.remove = function( id ){
    var rsids = this.recordIDs();
    if( !isInArray( rsids, id ) ){
        return false;
    }
    var key = this.key_r( id );
    this.db.store.remove( key );
    
    rsids = arrayRemoveValue( rsids, id );
    this.setRecordIDs( rsids );
    return true;
};
LocalDB_TB.prototype.clear = function(){
    var rsids = this.recordIDs();
    var i;
    for( i = 0; i < rsids.length; i++ ){
        var id = rsids[i];
        var key = this.key_r( id );
        this.db.store.remove( key );
    }
    this.db.store.remove( this.key_rs() );
    return true;
};
LocalDB_TB.prototype.update = function( id, rec ){
    var key = this.key_r( id );
    var value = JSON.stringify( rec );
    this.db.store.set( key, value );
    
    var rsids = this.recordIDs();
    if( !isInArray( rsids, id ) ){
        rsids.push( id );
        this.setRecordIDs( rsids );
    }
    return true;
};
LocalDB_TB.prototype.get = function( id ){
    var key = this.key_r( id );
    var value = this.db.store.get( key );
    if( !value ){
        return null;
    }
    var rec = JSON.parse( value );
    if( rec ){
        return rec;
    }
    return null;
};
LocalDB_TB.prototype.all = function(){
    var rs = [];
    var ids = this.recordIDs();
    var i;
    for( i = 0; i < ids.length; i++ ){
        var id = ids[i];
        var key = this.key_r( id );
        var value = this.db.store.get( key );
        if( value ){
            var r = JSON.parse( value );
            rs.push( [id,r] );
        }
    }
    if( rs ){
        return rs;
    }
    return [];
};


xinstore = new _LocalDB();
xinstore.db = new Object();
xinstore.dbs = [];
